# 优化复制功能

# 背景

最近遇到个复制的需求,在项目中找了下,发现存在写好的功能,于是直接调用,发现在chrome下居然是弹窗让我手动复制,于是看了下源码,居然是兼容古老的浏览器写法,在现在这个环境下已经失去了意义,所以动手优化一下。

# 实现

为了不影响之前的功能,只能用兼容的写法,在之前的一堆if-else的倒数第二处加个自己的判断。

if (window.clipboardData) {
	xxx
} else  if (navigator.userAgent.indexOf('Opera') != -1) {
	xxx
} else if (window.netscape) {
	xxx
} else if ($clipboard(content)) {
	在这里
} else {
	xxx
}

复制的逻辑主要参考了vue-clipboard2。

其主要原理就是创建一个textarea,将需要复制的值赋给textarea,然后选中,再执行复制操作document.execCommand('copy')即完成了操作。

注意下环境的兼容,ios设备上需要专门去选中textarea,才可以复制。

复制完将创建的内容都清了,避免内存泄漏。

主要改动在成功或失败都得返回结果告知上层函数,在失败时能走向最终的逻辑,也就是弹窗手动复制。

源码贴上

var $clipboard = function(input) {
	var value;
	var success = false;
	
	if (typeof input !== 'string') {
		try {
			value = JSON.stringify(input);
		} catch (e) {
			return false;
		}
	} else {
		value = input;
	}
	
	var textarea = document.createElement('textarea');
	
	textarea.value = value;
	textarea.setAttribute('readonly', '');
	textarea.style.cssText = 'position:fixed;pointer-events:none;z-index:-9999;opacity:0;';
	
	document.body.appendChild(textarea);
	
	if (navigator.userAgent.match(/ipad|ipod|iphone/i)) {
		textarea.contentEditable = true;
		textarea.readOnly = true;
		
		var range = document.createRange();
		
		range.selectNodeContents(textarea);
		
		var selection = window.getSelection();
		
		selection.removeAllRanges();
		// 让window选中textarea
		selection.addRange(range);
		// 设置textarea的光标选中位置为大致全部
		textarea.setSelectionRange(0, 999999);
	} else {
		textarea.select();
	}
	
	try {
		success = document.execCommand('copy');
	} catch (err) {
		console.warn(err);
	}
	
	document.body.removeChild(textarea);
	
	return success;
};